"""
自定义文件存储后端，来构造完整的图片url返回
"""

# Storage默认的文件存储后端
from django.core.files.storage import Storage
from django.conf import settings
from fdfs_client.client import Fdfs_client
import os

class FastDFSStorage(Storage):

    def __init__(self, fdfs_base_url=None):
        self.fdfs_base_url = fdfs_base_url or settings.FDFS_BASE_URL


    def _open(self, name, mode='rb'):
        """
        功能：打开django本地文件，用户保存传来的文件数据
        Args:
            name: 本地文件名
            mode: 打开的模式，如rb、wb...

        Returns: 本地文件对象
        """
        return None # 由于我们django把图片上传fdfs，并不需要保存本地，故此函数中无需打开一个文件对象返回


    def _save(self, name, file, max_length=None):
        """
        功能：实现文件的保存动作
        Args:
            name: 本地文件路径
            file: 浏览器传递过来的图片数据被封装成的图片文件对象
            max_length: 文件最大长度，默认为None表明长度不限制
        Returns: 返回值即为存储在mysql中的文件id值
        """
        # TODO:调用fdfs实现文件上传
        from fdfs_client.client import Fdfs_client
        from django.conf import settings
        from rest_framework import serializers
        conn = Fdfs_client(settings.FDFS_CONFIG_PATH)
        ret = conn.upload_by_buffer(file.read())
        if not (ret and ret['Status'] == 'Upload successed.'):
            raise serializers.ValidationError('图片上传失败！')
        file_id = ret['Remote file_id']

        return file_id

    def exists(self, name):
        """
        功能：判定django存储的本地文件是否已经存储，目的是为了避免重复保存
        返回值：True表示已存在则不会调用_save方法存储；False表示不存在则会调用_save方法存储
        """
        # 此处我们直接返回False表明django本地不存储任何数据，直接调用_save实现图片上传fdfs
        # fdfs会自定判定图片是否重复保存
        return False


    # Django项目一中实现的
    # 构造完整链接返回给浏览器用于访问图片
    def url(self, name):
        """
        功能：构建完整的图片文件url
        :param name: mysql中存储的文件索引id，比如：group1/M00/00/02/CtM3BVrPB4GAWkTlAAGuN6wB9fU4220429
        :return: 完整的图片url
        """
        return self.fdfs_base_url + name